#include<stdio.h>
#include<stdlib.h>
#include"node.h"

typedef struct Type_ *Type;
typedef struct FieldList_ *FieldList;
struct Type_ {
    enum {
        BASIC, ARRAY, STRUCTURE
    } kind;
    union {
        int basic;//0表示int 1表示float
        struct {
            Type elem;
            int size;
        } array;//元素类型,数组大小
        FieldList structure;//结构体类型
    } u;
};
struct FieldList_ {
    char *name;
    Type type;
    FieldList tail;
};
//符号表
struct TABLE {
    //为了方便和strcmp函数一致（相同字符串返回0，不同字符串返回1），设置0为是，1为否
    //结构体定义时的名字会放入符号表，但它不是一个可以使用的变量,因为实验三没有实现选做部分
    int is_def_struct;
    FieldList field;
    int linenumber;
    int variable;//用于实验三的变量,记录其为第几个变量，如t1，t2
    int is_from_func;//用于实验三的变量和地址类型的区分
    struct TABLE *next_for_openhash; //hash采用开散列法（有溢出桶的hash），指向下一个有相同hash值的符号
};
//函数表
struct FUNCTION {
    char *name;//函数名
    FieldList field;//参数列表
    Type return_type;//返回值
    int declaration;//该函数声明次数
    int definition;//该函数定义次数
    int linenumber;//函数所在行号,用于错误打印
    struct FUNCTION *next_for_openhash;//hash采用开散列法（有溢出桶的hash），指向下一个有相同hash值的函数
};
//P.J.Weinberger提出的散列函数
unsigned int hash_pjw(char *name);
//查找table表中是否出现name这个符号，出现则返回其对应TABLE
struct TABLE *find_symbol_in_table(char *name);
//查找function表中是否出现name这个函数，出现则返回其对应FUNCTION
struct FUNCTION *find_in_function(char *name);
//向函数表中添加一个函数
struct FUNCTION *add_to_function(struct FUNCTION *func);
//查看两个函数是否冲突
int conflict_between_functions(struct FUNCTION *funca, struct FUNCTION *funcb);
//比较属性链表是否完全相同
int fieldcmp(FieldList a, FieldList b);
//比较类型是否完全相同
int typecmp(Type a, Type b);
//比较函数列表是否相同，不看函数名
int fieldcmp_forfunc(FieldList a, FieldList b);
//将符号加入符号表
void add_to_table(FieldList fiel, int line, int is_def, int is_from_fun);
//在结构体中查找指定的属性
Type find_domain_in_struct(Type type, struct Node *now);
//在函数参数列表中中查找参数
int find_param_in_function(struct FUNCTION *func, struct Node *now);
//向符号表中加入read和write函数
void add_readwrite_tofunc();
//以下为语义分析的自顶向下递归分析的函数
//文法开始符
void Program(struct Node *now);
// 全局变量，结构体，函数的单个定义
void ExtDef(struct Node *now);
//类型描述符，基本类型或者结构体
Type Specifier(struct Node *now);
// 结构体
Type StructSpecifier(struct Node *now);
// 0个或多个Def
//judge=0,从struct语句中来
//judge=1,从变量语句中来，extdeclist\compst
//judge=2,从函数定义语句中来,paramdec
//1,2的区别在于，1需要加入符号表，2不需要加入符号表
FieldList DefList(struct Node *now, int judge);
// 定义局部变量
FieldList Def(struct Node *now, int judge);
// 0个或多个Dec
FieldList DecList(struct Node *now, Type type, int judge);
// 变量定义
FieldList Dec(struct Node *now, Type type, int judge);
// 定义变量
//judge=2函数定义，judge=3函数声明
FieldList VarDec(struct Node *now, Type type, int judge);
// 0个或多个ExtDef
void ExtDecList(struct Node *now, Type type);
// 定义函数头
//judge=0，函数声明
//在error判断以及是否加入符号表中会用到
//judge=1,函数定义
void FunDec(struct Node *now, Type type, int judge);
// 0个或多个ParamDec
FieldList VarList(struct Node *now, int judge);
// 定义形参
FieldList ParamDec(struct Node *now, int judge);
// 花括号括起来的语句块
void CompSt(struct Node *now, Type type);
// 0个或多个Stmt
void StmtList(struct Node *now, Type type);
// 语句
void Stmt(struct Node *now, Type type);
// 表达式
Type Exp(struct Node *now);
// 实参列表
FieldList Args(struct Node *now);
